package com.asset.service.impl;

import com.asset.common.ErrorCode;
import com.asset.exception.BusinessException;
import com.asset.exception.ThrowUtils;
import com.asset.manager.act.BudgetActManager;
import com.asset.mapper.AssetCategoryMapper;
import com.asset.mapper.BudgetMapper;
import com.asset.model.dto.approval.BudgetApproveRequest;
import com.asset.model.dto.approval.budget.BudgetAssetQuerRequest;
import com.asset.model.dto.approval.budget.BudgetQuerRequest;
import com.asset.model.dto.approval.budget.BudgetUpdateRequest;
import com.asset.model.entity.BudgetApplication;
import com.asset.model.entity.BudgetApplicationDetail;
import com.asset.model.entity.CascadeAssetCategory;
import com.asset.model.entity.User;
import com.asset.model.vo.LoginUserVO;
import com.asset.service.BudgetService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class BudgetServiceImpl implements BudgetService {
    @Resource
    private BudgetMapper budgetMapper;
    @Resource
    private BudgetActManager budgetActManager;
    @Resource
    private AssetCategoryMapper assetCategoryMapper;

    /**
     * 新增预算申请
     *
     * @param budgetApplication
     * @return
     */
    @Override
    public boolean addBudgetApplication(BudgetApplication budgetApplication, LoginUserVO user) {
        // 添加记录
        boolean r = budgetMapper.insertBudgetApplication(budgetApplication) > 0;
        // 启动流程（状态仍为草稿，等待用户提交）
        if (r && budgetApplication.getStatus() == 1) {
            // 获取该预算申请的名称
            String budgetName = budgetApplication.getBudgetName();
            // 设置流程变量
            Map<String, Object> variables = new HashMap<>();
            // 启动一个预算申请流程
            String pid = budgetActManager.startProcess(user,"预算申请",budgetName);
            // 查看该申请者的待办任务列表
            budgetActManager.getTasks(pid).forEach(task -> {
                // 打印任务信息
                log.info("任务ID：{}", task.getId());
                log.info("任务名称：{}", task.getName());
                log.info("任务创建时间：{}", task.getCreateTime());
                log.info("任务负责人：{}", task.getAssignee());
                log.info("流程实例ID：{}", task.getProcessInstanceId());
                log.info("流程定义ID：{}", task.getProcessDefinitionId());
                log.info("执行对象ID：{}", task.getExecutionId());
                log.info("任务描述：{}", task.getDescription());
            });
            // 预算申请关联流程实例ID
            budgetApplication.setWorkflowId(pid);
            // 设置流程状态状态为当前节点名称（谁申请、到谁审批
            budgetApplication.setApprovalStatus(budgetActManager.getTasks(pid).get(0).getName());
            // 更新数据库
            budgetMapper.updateWorkflowId(budgetApplication);
            log.info("该条预算申请数据：{}", budgetApplication);
        }
        return r;
    }

    /**
     * 根据 id 获取预算申请记录
     */
    @Override
    public BudgetApplication getBudgetApplicationById(Integer budgetId) {
        return budgetMapper.selectBudgetApplicationById(budgetId);
    }

    /**
     * 更新预算申请记录
     */
    @Override
    public boolean updateBudget(BudgetApplication budgetApplication) {
        return budgetMapper.updateBudget(budgetApplication) > 0;
    }

    @Override
    public boolean updateBudget(BudgetUpdateRequest budgetUpdateRequest) {
        Integer budgetId = budgetUpdateRequest.getBudgetId();
        String budgetName = budgetUpdateRequest.getBudgetName();
        Double totalAmount = budgetUpdateRequest.getTotalAmount();

        return false;
    }

    /**
     * 获取级联的资产类别列表
     */
    @Override
    public List<CascadeAssetCategory> getCascadeAssetCategoryList() {
        return assetCategoryMapper.selectCascadeAssetCategoryList();
    }

    /**
     * 添加一条预算申请详情
     */
    @Override
    public boolean addBudgetApplicationDetail(BudgetApplicationDetail budgetApplicationDetail) {
        return budgetMapper.insertBudgetApplicationDetail(budgetApplicationDetail) > 0;
    }

    /**
     * 分页获取预算申请列表
     *
     * @param budgetQuerRequest
     * @return
     */
    @Override
    public List<BudgetApplication> getBudgetApplicationList(BudgetQuerRequest budgetQuerRequest) {
        ThrowUtils.throwIf(budgetQuerRequest == null, ErrorCode.PARAMS_ERROR, "请求参数为空");

        Integer id = budgetQuerRequest.getId();
        String budgetName = budgetQuerRequest.getBudgetName();
        Integer status = budgetQuerRequest.getStatus();
        String approvalStatus = budgetQuerRequest.getApprovalStatus();

        return budgetMapper.selectBudgetApplicationQueryWrapper(id, budgetName, status, approvalStatus);
    }

    /**
     * 获取预算申请详情列表
     */
    @Override
    public List<BudgetApplicationDetail> getBudgetDetailQueryWrapper(BudgetAssetQuerRequest budgetAssetQuerRequest) {
        Integer id = budgetAssetQuerRequest.getId();
        Integer budgetApplicationId = budgetAssetQuerRequest.getBudgetApplicationId();
        String assetName = budgetAssetQuerRequest.getAssetName();
        Integer categoryId = budgetAssetQuerRequest.getCategoryId();

        return budgetMapper.selectBudgetDetailQueryWrapper(id, budgetApplicationId, assetName, categoryId);
    }

    /**
     * 领导审批预算
     */
    @Override
    public boolean approveBudgetByLeader(BudgetApproveRequest budgetApproveRequest, LoginUserVO loginUser) {
        // 获取该条预算申请记录
        Integer budgetApplicationId = budgetApproveRequest.getBudgetApplicationId();
        BudgetApplication budgetApplication = budgetMapper.selectBudgetApplicationById(budgetApplicationId);

        String pid = budgetApplication.getWorkflowId();                     // 获取流程实例ID
        String loginName = loginUser.getUsername();                         // 登录者用户名
        long isAdmin = loginUser.getIsAdmin();                              // 1资产部门员工 2部门领导
        String message = budgetApproveRequest.getApprovalResult();          // 审批结果
        String approvalOpinion = budgetApproveRequest.getApprovalOpinion(); // 审批意见
        Double totalAmount = budgetApproveRequest.getBudgetAmount();        // 审批金额

        // 领导领取任务
        budgetActManager.collectTask(loginName, pid);
        // 获取当前任务
        String taskId = budgetActManager.getTask(loginUser, pid);
        if (message.equals("同意")) {
            // 审批通过
            boolean r = budgetActManager.completeAgree(taskId, pid, approvalOpinion, totalAmount, budgetApplicationId);

            if (r) {
                // 更新数据库
                budgetApplication.setApprovalStatus("本公司领导审批通过");
                budgetApplication.setTotalAmount(totalAmount);          // 设置预算金额为审批的金额
                budgetMapper.updateBudget(budgetApplication);
                return true;
            }
        }
        return false;
    }

    /**
     * 删除一条预算申请的详细资产
     *
     * @param id 预算申请详情记录的id
     * @return
     */
    @Override
    public boolean delBudgetApplicationDetail(Integer id) {
        return budgetMapper.delBudgetApplicationDetail(id) > 0;
    }

    /**
     * 删除一条预算申请记录
     * @param budgetApplicationId 预算申请记录的id
     * @param userId              用户id
     * @return
     */
    @Override
    public boolean delBudgetApplication(Integer budgetApplicationId, Integer userId) {
        // 获取该条预算申请记录
        BudgetApplication budgetApplication = budgetMapper.selectBudgetApplicationById(budgetApplicationId);

        int status = budgetApplication.getStatus();
        Integer id = budgetApplication.getApplicantId();
        // 怎么保证只能删除自己的草稿？
        if (status == 1 && id.equals(userId)) {
            return budgetMapper.delBudgetApplication(budgetApplicationId) > 0;
        }
        return false;
    }
}
